// src/utils/http.ts
import axios from 'axios'

import type {
  AxiosInstance,
  AxiosRequestConfig,
  AxiosResponse,
  InternalAxiosRequestConfig,
} from 'axios'

import envConstant from '@/constant/env'

axios.defaults.withCredentials = true

// 定义后端返回的数据结构泛型接口
export interface ResponseData<T = any> {
  successful: boolean;
  code: number;
  message?: string;
  payload?: T;
}

enum ErrorMessage {
  MSG_DEFAULT = '请求失败',
  MSG_400 = '请求错误',
  MSG_401 = '未认证，请登录后访问',
  MSG_403 = '未授权，拒绝访问',
  MSG_404 = '请求地址错误',
  MSG_500 = '服务错误',
  MSG_NETWORK_ERROR = '网络错误',
}

enum AuthenticationHeaders {
  X_AUTH_TYPE = 'X_AUTH_TYPE',
  X_AUTH_TOKEN = 'X_AUTH_TOKEN',

}

enum AuthenticationTranType {
  HEADER = 'header',
  COOKIE = 'cookie',
}


// 创建自定义配置的 Axios 实例
const createAxiosInstance = (config?: AxiosRequestConfig): AxiosInstance => {
  const instance = axios.create({
    baseURL: envConstant.BASE_URL,
    timeout: 10000,
    headers: {
      'Content-Type': 'application/json;charset=UTF-8',
    },
    ...config,
  });

  return instance;
};

const http = createAxiosInstance();

// 请求拦截器
http.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // 在发送请求前处理，如添加 token
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 响应拦截器
http.interceptors.response.use(
  (response: AxiosResponse<ResponseData>) => {
    const res = response.data;
    // 处理业务逻辑错误
    if (!res.successful) {
      // 根据错误码处理特定逻辑，如 token 过期
      if (res.code === 401) {
        window.location.href = '/login';
      }
      return Promise.reject(new Error(res.message || ErrorMessage.MSG_DEFAULT));
    }
    return res.payload; // 直接返回业务数据
  },
  (error) => {
    // 处理 HTTP 错误状态码
    const status = error.response?.status;
    let message = ErrorMessage.MSG_DEFAULT;
    switch (status) {
      case 400:
        message = ErrorMessage.MSG_400;
        break;
      case 401:
        message = ErrorMessage.MSG_401;
        window.location.href = '/login';
        break;
      case 403:
        message = ErrorMessage.MSG_403;
        break;
      case 404:
        message = ErrorMessage.MSG_404;
        break;
      case 500:
        message = ErrorMessage.MSG_500;
        break;
      default:
        message = ErrorMessage.MSG_NETWORK_ERROR;
    }
    return Promise.reject(new Error(message));
  }
);

// 封装 GET 请求
export const get = <T>(url: string, params?: object, config?: AxiosRequestConfig): Promise<T> => {
  return http.get(url, { params, ...config });
};

// 封装 POST 请求
export const post = <T>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> => {
  return http.post(url, data, config);
};

// 封装 PUT 请求
export const put = <T>(url: string, data?: object, config?: AxiosRequestConfig): Promise<T> => {
  return http.put(url, data, config);
};

// 封装 DELETE 请求
export const del = <T>(url: string, data?: object): Promise<T> => {
  return http.delete(url, data);
};

// 文件上传
export const uploadFile = (path: string, file: File) => {
  const formData = new FormData();
  formData.append('file', file);
  return http.post(path, formData, {
    headers: { 'Content-Type': 'multipart/form-data' },
  });
};
